// 学习 axios
console.log('axios => ', axios)

// axios 就是把 js 的 http 请求封装起来了
// 用 Promise 的形式封装的

// axios 的语法
/*
  基础使用
  axios({ 配置项 })
    => url: '', 请求地址, 必填
    => method: '', 请求方式, 默认值是 GET【 GET，POST，DELETE，HEAD，PUT，PATCH，OPTIONS 】
    => params: {}, 可以是个字符串也可以是个对象, GET 请求的携带参数
    => data: {}, POST 请求的携带参数
    => timeout: 1000, 超时时间, 默认是无限
    => headers: {}, 补充设置请求头
    => ...
  axios 的方法
    axios.get(url[, options])
    axios.delete(url[, options])
    axios.head(url[, options])
    axios.options(url[, options])

    axios.post(url[, data[, options]])
    axios.put(url[, data[, options]])
    axios.patch(url[, data[, options]])
*/

// axios({
//   url: 'http://localhost:8080/b1',
//   method: 'POST',
//   headers: {
//     authorization: 'sdfgadk'
//   }
// })
//   .then(res => {
//     // 请求成功后会执行
//     // res 不是服务器返回的响应, 是被 axios 包装过的响应
//     // res === { ..., data: 服务端给回的响应 }
//     console.log(res)
//   })
//   .catch(err => {
//     // 请求失败后会执行
//   })

// 专门发送get请求
// axios.get('http://localhost:8080/a2', { params: { name: 'Jack' } })
//   .then(res => {
//     // 请求成功后会执行
//     // res 不是服务器返回的响应, 是被 axios 包装过的响应
//     // res === { ..., data: 服务端给回的响应 }
//     console.log(res)
//   })
//   .catch(err => {
//     // 请求失败后会执行
//   })

// 专门发送 post 请求
// axios.post('http://localhost:8080/b2', { name: 'Jack', age: 18 })
//   .then(res => {
//     // 请求成功后会执行
//     // res 不是服务器返回的响应, 是被 axios 包装过的响应
//     // res === { ..., data: 服务端给回的响应 }
//     console.log(res)
//   })
//   .catch(err => {
//     // 请求失败后会执行
//   })

/*
  axios 实例使用
    + 可以利用 axios 提供的 create 函数创建一个 axios 实例
    + 语法: axios.create({ 基础配置项 })
    + 返回值: 一个 axios 实例
      => 注意: axios 实例和 axios 的使用方式一模一样
*/
// const instance = axios.create({
//   baseURL: 'http://localhost:8080'
// })

// instance.post('/b2', { name: 'Jack', age: 18 })
//   .then(res => {
//     // 请求成功后会执行
//     // res 不是服务器返回的响应, 是被 axios 包装过的响应
//     // res === { ..., data: 服务端给回的响应 }
//     console.log(res)
//   })
//   .catch(err => {
//     // 请求失败后会执行
//   })


/*
  axios 实例可以挂载两个拦截器
    => 请求拦截器
      -> 发送出去之前
      -> 实例.interceptors.request.use(函数)
    => 响应拦截器
      -> 收到响应以后, 浏览器解析响应完毕, 把响应内容给到 axios 以后, 没有给到本次请求之前
      -> 实例.interceptors.response.use(函数)
*/
const instance = axios.create({
  baseURL: 'http://localhost:8080'
})

instance.interceptors.request.use((config) => {
  // config 就是本次请求的配置项
  console.log(config)

  // 经常在这里去添加 token 或者加一些统一设置
  config.headers.authorization = 'ajsgdhjkad'

  // 开启 loading 效果

  // 在这个函数内, 必须要 return config 才是放过本次请求
  // 如果没有 return config, 相当于本次请求没有发送

  return config
}, () => {})

instance.interceptors.response.use(response => {
  // response 就是浏览器解析完毕, 被 axios 包装过得响应

  console.log(response)

  // 一般会做统一错误判断
  // if (response.status !== 200) {
  //   // 表示本次请求失败了
  // }

  // if (response.data.code !== 1) {
  //   // 表示本次请求成功了, 但是因为各种原因, 导致服务器给出的错误
  // }

  // 关闭 loading

  // 这个函数内, 必须要有 返回值, 那么你书写请求的地方才能拿到结果
  // 如果没有 返回值, 那么你书写请求的地方没有结果
  // 这里 return 什么. 你书写请求的位置 then(res) 接受到的就是什么

  return response.data
})

// instance.post('/b2')
//   .then(res => {
//     // 请求成功后会执行
//     // res 不是服务器返回的响应, 是被 axios 包装过的响应
//     // res === { ..., data: 服务端给回的响应 }
//     console.log(res)
//   })
//   .catch(err => {
//     // 请求失败后会执行
//   })


// 目前: 有了 instance 实例
// async function getInfo() {
//   // 发请求
//   try {
//     const res = await instance.get('/a1')
//     console.log('成功', res)
//   } catch (err) {
//     console.log('服务器挂了, 稍等')
//   }
// }

// getInfo()

// 封装一个请求
function axiosGet() {
  return new Promise(resolve => {
    instance
      .get(...arguments)
      .then(res => resolve({ code: 1, res }))
      .catch(err => resolve({ code: 0, err }))
  })
}

async function getInfo() {
  const { code, err, res } = await axiosGet('/a1')

  if (code === 0) {
    // 虽然这个 Promise 成功了, 但是本次请求返回的事失败
    console.log('服务器挂了, xxx')
    return
  }

  console.log('成功', res)
}

getInfo()
